package com.zhang.study.chapter03;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static com.zhang.util.RandomArrayUtil.generateRandomArray;

/**
 * 使用数组实现栈
 */
public class Code06_ArrayMyStack {
    /**
     * 实现两个方法 一个入栈一个出栈
     * 最好再来一个peek方法 查看栈中弹出哪个元素 但不是真正弹出只是查看
     */
    public static class ArrayMyStack<T> {
        public ArrayList<T> stack;

        public ArrayMyStack(int size) {
            this.stack = new ArrayList<>(size);
        }

        public void push(T value) {
            stack.add(value);
        }

        public T pop() {
            if (stack.isEmpty()) {
                throw new RuntimeException("stack is empty!");
            }
            int index = stack.size() - 1;
            return stack.remove(index);
        }

        public T peek() {
            if (stack.isEmpty()) {
                return null;
            }
            int index = stack.size() - 1;
            return stack.get(index);
        }


    }


    public static void main(String[] args) {
        int len = 5;
        int value = 100;
        int testTime = 10000;
        int sizeTime;
        System.out.println("test begin!");
        for (int i = 0; i < testTime; i++) {
            // 生成链表头结点
            int[] intArr = generateRandomArray(len, value);
            List<Integer> collect = IntStream.of(intArr).boxed().collect(Collectors.toList());
            Code04_NodeMyStack.NodeMyStack<Integer> nodeMyStack = new Code04_NodeMyStack.NodeMyStack<>(collect);
            ArrayMyStack<Integer> stack = new ArrayMyStack<>(collect.size());
            for (Integer integer : collect) {
                stack.push(integer);
            }
            sizeTime = collect.size() - 1;
            if (!testMyStack(nodeMyStack, stack, sizeTime)) {
                System.out.println("Oops!");
            }
        }
        System.out.println("test finish!");
    }

    private static boolean testMyStack(Code04_NodeMyStack.NodeMyStack<Integer> nodeMyStack, ArrayMyStack<Integer> stack, int sizeTime) {
        int times = sizeTime;
        while (times >= 0) {
            double random = Math.random();
            int i = (int) (Math.random() * 100 - Math.random() * 10);
            if (random >= 0.5) {
                // 入栈
                nodeMyStack.push(i);
                stack.push(i);
            } else {
                // 出栈
                Integer pop1 = nodeMyStack.pop();
                Integer pop2 = stack.pop();
                if (!Objects.equals(pop1, pop2)) {
                    return false;
                }
            }
            times--;
        }
        while (stack.peek() != null) {
            Integer pop1 = stack.pop();
            Integer pop2 = nodeMyStack.pop();
            if (!Objects.equals(pop1, pop2)) {
                return false;
            }
        }
        return true;
    }


}
